// 
// background-model.cpp
//
// Author: vietcuong
// Description: detect background and foreground
//

#include <stdio.h>
#include <stdlib.h>


#include "cv.h"
#include "highgui.h"

#include "average_background.h"
#include "codebook.h"

AverageBackground avg_bg;
Codebook codebook;
float avg_scale_low, avg_scale_high;
IplImage *ImaskAVG;
IplImage *yuvImage;
IplImage *ImaskCodebook;

int is_initialize = 0;

void initialize(IplImage *image) {
    is_initialize = 1;

    avg_bg.init(image);
    codebook.init(image);

    ImaskAVG = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
    ImaskCodebook = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);

    cvSet(ImaskAVG, cvScalar(255));
    cvSet(ImaskCodebook, cvScalar(255));
}

int main(int argc, char **argv) {
    // Get parameters
    char *filename;

    int start_capture, end_capture;

    filename = argv[1];
    
    start_capture = 1;
    end_capture = 50;

    // Main processing loop
    CvCapture *capture = 0;
    IplImage *raw_image;

    capture = cvCreateFileCapture(filename);
    if (!capture) {
        printf("Can not open file %s\n", filename);
        return 0;
    }

    printf("123\n");
    // Create display window
    cvNamedWindow("Raw", 1);
    cvNamedWindow("Average model", 1);

    int frame_index = 0;
    bool pause = false;
    bool single_step = false;

    while (1) {
        // Get the next image
        if (!pause) {
            raw_image = cvQueryFrame(capture);
            frame_index++;
        
            if (frame_index == 56) {
                pause = true;
            }
        }

        if (single_step) {
            pause = true;
        }

        printf("frame_index = %i\n", frame_index);
        
        if (!raw_image) {
            if (is_initialize) {
                avg_bg.deallocate_images();
            }

            cvDestroyWindow("Raw");
            cvDestroyWindow("Average model");

            return 1;
        }

        // First time
        if (frame_index == 1) {
            // initialize
            initialize(raw_image);
        }

        printf("frame index = %i\n", frame_index);
        // Accumulate the back ground
        if ((!pause) && (start_capture <= frame_index) && (frame_index < end_capture)) {
            avg_bg.accumulate_background(raw_image);
        }

        // Create avg model
        if (frame_index == end_capture) {
            avg_bg.create_model();
        }

        // Find the foreground if any
        if (frame_index >= end_capture) {
            // Find foreground by avg background method
            avg_bg.find_foreground(raw_image, ImaskAVG);

            // Find foreground by code book method
            codebook.find_foreground(raw_image, ImaskCodebook);
        }

        // Display
        cvShowImage("Raw", raw_image);
        cvShowImage("Average model", ImaskAVG);
        cvShowImage("Foreground Codebook", ImaskCodebook);
     
        // system("pause");
        char ch = cvWaitKey(10)&0xFF;

        if (ch == 27 || ch == 'q' || ch == 'Q') {
            break;
        }

        switch (ch) {
            case 'p':
                pause ^= 1;
                break;
            case 's':
                single_step = true;
                pause = false;
                break;
        }
    }


    cvDestroyWindow("Raw");
    cvDestroyWindow("Average model");
    avg_bg.deallocate_images();

    return 0;
}
